﻿' Copyright (c) Microsoft Corporation.  All rights reserved.

Partial Public Class TravelPage
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        ' check the post back
        If IsPostBack Then
            Return
        End If

        ' get the blog id from the page request.
        Dim blogID = 0
        Integer.TryParse(Request.Params("BlogID"), blogID)
        ViewState("BlogID") = blogID

        ' create a short lived context and send back the travel blogs.
        Using travelEntities As New MyTravelEntities()

            If travelEntities.BlogPosts.Any(Function(b) b.Blog.BlogID = blogID) Then
                ' get the last blog post and span in the Blog and Person information.
                Dim post = (From bp In travelEntities.BlogPosts.Include("Blog.Person") _
                                                               .Include("Comments") _
                                 Where bp.Blog.BlogID = blogID _
                                 Order By bp.BlogDate Descending _
                                 Select bp).First()

                If post IsNot Nothing Then
                    ' fill in the new text.
                    labelBlogTitle.Text = post.BlogTitle

                    labelSeries.Text = post.Blog.SeriesTitle

                    labelPerson.Text = post.Blog.Person.Name
                    blogEntry.Text = post.BlogEntry

                    ' call the methods to update the comments.
                    UpdatePostComments(travelEntities, post.BlogPostID)

                    ' not set all the people in the dropdown list
                    dropdownPersons.DataTextField = "Name"
                    dropdownPersons.DataSource = travelEntities.People
                    dropdownPersons.DataBind()

                    ' setup the viewstate that we need in the submit button
                    ViewState("BlogPost") = post
                    ViewState("People") = travelEntities.People.ToList()
                End If
            End If
        End Using
    End Sub

    ' this helps in the refresh problem where the operation gets redone.
    Private Sub ReloadPage()
        Dim blogID = ViewState("BlogID")
        Response.Redirect("TravelPage.aspx?BlogID=" & blogID.ToString())
    End Sub
    Protected Sub ButtonDeleted_Click(ByVal sender As Object, ByVal e As EventArgs) Handles ButtonDeleted.Click
        ' create a short lived context and send back the travel blogs.
        Using travelEntities As New MyTravelEntities()
            ' get the comment to delete
            Dim commentIndex = gridComments.SelectedIndex
            If commentIndex > -1 Then
                ' get the blog post and attach.
                ' because this is binary, the comments are also serialized
                Dim post = DirectCast(ViewState("BlogPost"), BlogPost)
                travelEntities.Attach(post)

                ' get the comment, and delete.
                Dim toDelete = post.Comments.ElementAt(commentIndex)

                ' no call delete
                travelEntities.DeleteObject(toDelete)
                ' once you have the reference, the properties are changed
                ' tracked so modifications are update during SaveChanges

                Try
                    travelEntities.SaveChanges()
                Catch ex As OptimisticConcurrencyException
                    ' catching this exception allows you to 
                    ' refresh entities with either store/client wins
                    ' project the entities into this failed entities.
                    Dim failedEntities = From e1 In ex.StateEntries _
                                         Select e1.Entity

                    ' Note: in future you should be able to just pass the opt.StateEntities in to refresh.
                    travelEntities.Refresh(RefreshMode.ClientWins, failedEntities.ToList())
                    travelEntities.SaveChanges()
                End Try
            End If
            ReloadPage()
        End Using
    End Sub

    Protected Sub ButtonUpdated_Click(ByVal sender As Object, ByVal e As EventArgs) Handles ButtonUpdated.Click
        ' create a short lived context and send back the travel blogs.
        Using travelEntities As New MyTravelEntities()
            ' get the comments to update.
            Dim commentIndex = gridComments.SelectedIndex
            If commentIndex > -1 Then
                ' get the blog post and attach.
                ' because this is binary, the comments are also serialized
                Dim post = DirectCast(ViewState("BlogPost"), BlogPost)
                travelEntities.Attach(post)

                ' get the comment and update the text.
                Dim toUpdate = post.Comments.ElementAt(commentIndex)

                toUpdate.CommentText += "*"

                Try
                    travelEntities.SaveChanges()
                Catch ex As OptimisticConcurrencyException
                    ' catching this exception allows you to 
                    ' refresh entities with either store/client wins
                    ' project the entities into this failed entities.
                    Dim failedEntities = From e1 In ex.StateEntries _
                                         Select e1.Entity

                    ' Note: in future you should be able to just pass the opt.StateEntities in to refresh.
                    travelEntities.Refresh(RefreshMode.ClientWins, failedEntities.ToList())
                    travelEntities.SaveChanges()
                End Try
            End If

            ReloadPage()
        End Using

    End Sub

    Protected Sub buttonSubmitComment_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonSubmitComment.Click
        ' create a short lived context and send back the travel blogs.
        Using travelEntities As New MyTravelEntities()
            Dim post = DirectCast(ViewState("BlogPost"), BlogPost)
            Dim peopleList = ViewState("People")

            ' get the person from the people list
            Dim person = DirectCast(peopleList(dropdownPersons.SelectedIndex), Person)

            ' attach the post and the person that wrote the blog.
            travelEntities.Attach(post)

            ' created a new comment and attach the travel entities.
            Dim newComment = New Comment() With { _
                                            .CommentText = textComment.Text, _
                                            .BlogPost = post}

            newComment.PersonReference.EntityKey = person.EntityKey

            Try
                travelEntities.SaveChanges()
            Catch ex As OptimisticConcurrencyException
                ' catching this exception allows you to 
                ' refresh entities with either store/client wins
                ' project the entities into this failed entities.
                Dim failedEntities = From e1 In ex.StateEntries _
                                     Select e1.Entity

                ' Note: in future you should be able to just pass the opt.StateEntities in to refresh.
                travelEntities.Refresh(RefreshMode.ClientWins, failedEntities.ToList())
                travelEntities.SaveChanges()
            End Try

            ' clear the text.
            textComment.Text = ""

            ReloadPage()
        End Using
    End Sub

    Sub UpdatePostComments(ByRef travelEntities As MyTravelEntities, ByVal blogPostID As Integer)
        ' because the query is no tracking, we need to include the people of the
        ' comments.
        Dim comments = From c In travelEntities.Comments _
                           Where c.BlogPost.BlogPostID = blogPostID _
                           Select Author = c.Person.Name, _
                                  WhatISaid = c.CommentText
        gridComments.DataSource = comments
        gridComments.DataBind()
    End Sub
End Class